package com.vv.tools.modules.utils.domain.service.impl;

import com.vv.tools.common.util.CacheUtil;
import com.vv.tools.common.util.FileUtils;
import com.vv.tools.common.util.JsonUtil;
import com.vv.tools.modules.auth.service.CozeAuthService;
import com.vv.tools.modules.utils.domain.model.CurlRequestBO;
import com.vv.tools.modules.utils.domain.model.QccProgressBO;
import com.vv.tools.modules.utils.domain.service.CurlService;
import com.vv.tools.modules.utils.domain.service.QccAsyncService;

import jakarta.annotation.Resource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @author wen.li
 */
@Service
public class QccAsyncServiceImpl implements QccAsyncService {

    private static final String FILE_PATH = "classpath:config/coze.json";

    private static final Map<String, QccProgressBO> MAP = new ConcurrentHashMap<>();

    private CurlRequestBO initConfig;

    @Resource
    private CurlService curlService;

    @Resource
    private CozeAuthService cozeAuthService;

    @Override
    public void set(String key, QccProgressBO qccProgressBO) {
        MAP.put(key, qccProgressBO);
    }

    @Override
    public QccProgressBO get(String key) {
        return MAP.get(key);
    }

    @Async
    @Override
    public void run(String requestId) {
        QccProgressBO requestBO = get(requestId);
        requestBO.setInvalid(false);

        // 获取初始配置
        if (null == initConfig) {
            initConfig = init();
        }

        // 进度条
        int progress = 0;

        Set<String> needQuery = new HashSet<>();

        // 缓存过滤
        for (String bd : requestBO.getBatchData()) {
            progress++;
            requestBO.setProgress((int) (((float) progress / requestBO.getBatchData().size()) * 100));

            // 处理特殊字符
            String data = handleData(bd);

            // 读缓存
            if (StringUtils.isBlank(data) || CacheUtil.containsKey(data)) {
                continue;
            }

            needQuery.add(data);
        }

        if (CollectionUtils.isNotEmpty(needQuery)) {
            String token = cozeAuthService.getToken();
            initConfig.setGlobalVariables(Map.of("token", token));

            needQuery.forEach(data -> {
                initConfig.setBatchData(Collections.singletonList(Map.of("data", data)));
                List<String> curlList = curlService.curl(initConfig);
                if (CollectionUtils.isNotEmpty(curlList)) {
                    String result = handleResponse(curlList.get(0));
                    // 写缓存
                    if (StringUtils.isNotBlank(result)) {
                        CacheUtil.put(data, result);
                    }
                }
            });
        }

        // 组装结果
        List<String> result = new ArrayList<>();
        requestBO.getBatchData().forEach(o ->
            result.add(CacheUtil.get(o))
        );
        requestBO.setProgress(100);
        requestBO.setResultData(result);

        // 删除缓存
        delete(requestId);
    }

    private String handleResponse(String response) {
        if (StringUtils.isBlank(response)) {
            return null;
        }
        String valid = "^(.+省|.+市|.+区|.+香港|.+澳门)";
        Matcher matcher = Pattern.compile(valid).matcher(response);
        if (matcher.find()) {
            return response.trim();
        }
        return null;
    }

    private String handleData(String data) {
        String result = data;
        if (data.contains("\"")) {
            result = data.replace("\"", "");
        }
        if (data.contains("\t")) {
            result = data.replace("\t", "");
        }
        return result.trim();
    }

    private void delete(String requestId) {
        // 缓存30s
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException ignored) {
        }
        MAP.remove(requestId);
    }

    private CurlRequestBO init() {
        String s = FileUtils.read(Objects.requireNonNull(FileUtils.getClassPathFile(FILE_PATH)));
        return JsonUtil.toObject(s, CurlRequestBO.class);
    }

}
